package cn.agiledata.bank.audit.action;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import cn.agiledata.bank.account.service.AccountSummary;
import cn.agiledata.bank.audit.exception.AuditException;
import cn.agiledata.bank.audit.form.AuditRuleForm;
import cn.agiledata.bank.audit.service.AuditGroupService;
import cn.agiledata.bank.audit.service.AuditRuleService;
import cn.agiledata.bank.audit.service.AuditStepService;
import cn.agiledata.bank.common.bean.LabelIntEnum;
import cn.agiledata.bank.common.servlet.InitForString;
import cn.agiledata.bank.common.util.Constant;
import cn.agiledata.bank.common.util.WeatherUtil;
import cn.agiledata.bank.hibernateBean.AuditGroup;
import cn.agiledata.bank.hibernateBean.AuditOperandType;
import cn.agiledata.bank.hibernateBean.AuditRule;
import cn.agiledata.bank.hibernateBean.AuditStep;
import cn.agiledata.bank.hibernateBean.Operator;
import cn.agiledata.bank.hibernateBean.Sysbook;
import cn.agiledata.bank.myspace.action.AbstractMySpaceAction;
import cn.agiledata.bank.transaction.audit.service.CompanyAuditService;
import com.vnv.infrastructure.exception.IPBException;
import com.vnv.infrastructure.logic.IPBAppFactory;

/**
 * @author 马贤波
 * 
 */
public class AuditRuleAction extends AbstractMySpaceAction {

    private AuditGroupService getAuditGroupService() {
        return (AuditGroupService) IPBAppFactory.getObj("auditGroupService");
    }

    private AuditRuleService getAuditRuleService() {
        return (AuditRuleService) IPBAppFactory.getObj("auditRuleService");
    }

    private AuditStepService getAuditStepService() {
        return (AuditStepService) IPBAppFactory.getObj("auditStepService");
    }

//    private IMySpaceService getMySpaceService() {
//        return (IMySpaceService) IPBAppFactory.getObj("mySpaceService");
//    }

    private CompanyAuditService getCompanyAuditService() {
        return (CompanyAuditService) IPBAppFactory
                .getObj("companyAuditService");
    }

    public ActionForward getAuditRuleList(ActionMapping mapping,
            ActionForm actionForm, HttpServletRequest request,
            HttpServletResponse response) throws IPBException, Exception {
        long accountId = WeatherUtil.getLoingInfoFromSession(request)
                .getAccountId();
        request.setAttribute("ResultList", getCompanyAuditService()
                .getEnabledUserAuditRuleList(accountId));
        return mapping.findForward("success");
    }

    public ActionForward preAddAuditRule(ActionMapping mapping,
            ActionForm actionForm, HttpServletRequest request,
            HttpServletResponse response) throws IPBException, Exception {
        AuditRuleForm form = (AuditRuleForm) actionForm;
        form.reset();
        request.setAttribute("auditSteps", form.getAuditSteps());
        request.setAttribute("transactionTypeList", getAuditRuleService()
                .getAuditOperandTypes(false));
        request.setAttribute("validList", getValidList());

        return mapping.findForward("success");
    }

    private List getValidList() throws InstantiationException,
            IllegalAccessException {
        List validSysbookList = (List) InitForString.dataDictMap.get("VALID");
        List validList = (List) validSysbookList.getClass().newInstance();
        for (int i = 0; i < validSysbookList.size(); i++) {
            Sysbook validSysbook = (Sysbook) validSysbookList.get(i);
            int value = Integer.parseInt(validSysbook.getId().getListId());
            validList.add(new LabelIntEnum(value, validSysbook.getListName()));
        }
        return validList;
    }

    private Operator getCurrentOperator(HttpServletRequest request) {
        Operator operator = WeatherUtil.getOperator(request);
        if (operator == null) {
            List operators = WeatherUtil.getLoingInfoFromSession(request)
                    .getOperatorList();
            operator = (Operator) operators.get(0);
        }
        return operator;
    }

    public ActionForward addAuditRule(ActionMapping mapping,
            ActionForm actionForm, HttpServletRequest request,
            HttpServletResponse response) throws IPBException, Exception {
        Operator operator = getCurrentOperator(request);
        AuditRuleForm form = (AuditRuleForm) actionForm;
        long transactionTypeId = form.getTransactionTypeId();
        String name = form.getName();
        int valid = form.getValid();
        AuditStep[] auditSteps = form.getAuditSteps();
        AuditRule auditRule = getAuditRuleService().addUserAuditRule(operator,
                transactionTypeId, name, valid, auditSteps);
        request.setAttribute("auditSteps", auditSteps);
        AuditOperandType transactionType = auditRule.getAuditOperandType();
        request.setAttribute("transactionType", transactionType);
        request.setAttribute("used", new Integer(auditRule.getUsed()));
        return mapping.findForward("success");
    }

    public ActionForward preAmendAuditRule(ActionMapping mapping,
            ActionForm actionForm, HttpServletRequest request,
            HttpServletResponse response) throws IPBException, Exception {
        AuditRuleForm form = (AuditRuleForm) actionForm;
        long id = form.getId().longValue();
        AuditRule auditRule = getAuditRuleService().getAuditRuleById(id);
        form.setName(auditRule.getName());
        form.setValid(auditRule.getValid());
        if (!form.getSetAuditStep()) {
            form.setAuditSteps((AuditStep[]) auditRule.getAuditSteps().toArray(
                    new AuditStep[0]));
        }
        request.setAttribute("auditSteps", form.getAuditSteps());
        boolean used = Constant.USED_YES == auditRule.getUsed();
        AuditOperandType transactionType = auditRule.getAuditOperandType();
        if (used) {
            request.setAttribute("transactionType", transactionType);
        } else {
            form.setTransactionTypeId(transactionType.getId().longValue());
            request.setAttribute("transactionTypeList", getAuditRuleService()
                    .getAuditOperandTypes(false));
        }
        request.setAttribute("validList", getValidList());
        request.setAttribute("used", new Integer(auditRule.getUsed()));
        return mapping.findForward(used ? "used" : "unused");
    }

    public ActionForward amendAuditRule(ActionMapping mapping,
            ActionForm actionForm, HttpServletRequest request,
            HttpServletResponse response) throws IPBException, Exception {
        AuditRuleForm form = (AuditRuleForm) actionForm;
        Operator operator = getCurrentOperator(request);
        long id = form.getId().longValue();
        long transactionTypeId = form.getTransactionTypeId();
        String name = form.getName();
        int valid = form.getValid();
        AuditStep[] auditSteps = form.getAuditSteps();
        AuditRule auditRule = getAuditRuleService().amendUserAuditRule(id,
                operator, transactionTypeId, name, valid, auditSteps);
        request.setAttribute("auditSteps", auditSteps);
        AuditOperandType transactionType = auditRule.getAuditOperandType();
        request.setAttribute("transactionType", transactionType);
        request.setAttribute("used", new Integer(auditRule.getUsed()));
        return mapping.findForward("success");
    }

    public ActionForward removeAuditRule(ActionMapping mapping,
            ActionForm actionForm, HttpServletRequest request,
            HttpServletResponse response) throws IPBException, Exception {
        long auditRuleId = Long.parseLong(request.getParameter("id"));
        if (!getAuditRuleService().removeAuditRule(auditRuleId)) {
            throw AuditException.AUDIT_RULE_USED_CANNOT_REMOVE;
        }
        return mapping.findForward("success");
    }

    public ActionForward preAddAuditStep(ActionMapping mapping,
            ActionForm actionForm, HttpServletRequest request,
            HttpServletResponse response) throws IPBException, Exception {
        ((AuditRuleForm) actionForm).reset();
        long accountId = WeatherUtil.getLoingInfoFromSession(request)
                .getAccountId();
        request.setAttribute("auditGroups", getAuditGroupService()
                .getUserAuditGroupList(accountId));
        return mapping.findForward("success");
    }

    public ActionForward addAuditStep(ActionMapping mapping,
            ActionForm actionForm, HttpServletRequest request,
            HttpServletResponse response) throws IPBException, Exception {
        AuditRuleForm form = (AuditRuleForm) actionForm;
        String auditStepName = form.getAuditStepName();
        Long auditGroupId = form.getAuditGroupId();
        AuditGroup auditGroup = auditGroupId == null ? null
                : getAuditGroupService().getAuditGroupById(
                        auditGroupId.longValue());
        AuditStep[] auditSteps = form.getAuditSteps();
        Operator operator = getCurrentOperator(request);
        form.setAuditSteps(getAuditStepService().appendAuditStep(
                operator.getId(), auditStepName, auditGroup, auditSteps));
        if (form.getId() == null)
            return mapping.findForward("add");
        else
            return mapping.findForward("amend");
    }

    public ActionForward removeAuditStep(ActionMapping mapping,
            ActionForm actionForm, HttpServletRequest request,
            HttpServletResponse response) throws IPBException, Exception {
        AuditRuleForm form = (AuditRuleForm) actionForm;
        form.setAuditSteps(getAuditStepService().removeAuditStep(
                form.getAuditSteps(), form.getAuditStepLevel() + 1));
        if (form.getId() == null)
            return mapping.findForward("add");
        else
            return mapping.findForward("amend");
    }

    public ActionForward preAmendAuditStep(ActionMapping mapping,
            ActionForm actionForm, HttpServletRequest request,
            HttpServletResponse response) throws IPBException, Exception {
        AuditRuleForm form = (AuditRuleForm) actionForm;
        AuditStep[] auditSteps = form.getAuditSteps();
        int level = form.getAuditStepLevel();
        AuditStep auditStep = getAuditStepService().getAuditStepByLevel(
                auditSteps, level);
        form.setAuditStepName(auditStep.getName());
        Long auditGroupId = auditStep.getAuditGroup() == null ? null
                : auditStep.getAuditGroup().getId();
        form.setAuditGroupId(auditGroupId);
        request.setAttribute("auditGroupId", auditGroupId);
        long accountId = WeatherUtil.getLoingInfoFromSession(request)
                .getAccountId();
        request.setAttribute("auditGroups", getAuditGroupService()
                .getUserAuditGroupList(accountId));
        return mapping.findForward("success");
    }

    public ActionForward amendAuditStep(ActionMapping mapping,
            ActionForm actionForm, HttpServletRequest request,
            HttpServletResponse response) throws IPBException, Exception {
        AuditRuleForm form = (AuditRuleForm) actionForm;
        String auditStepName = form.getAuditStepName();
        Long auditGroupId = form.getAuditGroupId();
        AuditGroup auditGroup = auditGroupId == null ? null
                : getAuditGroupService().getAuditGroupById(
                        auditGroupId.longValue());
        AuditStep[] auditSteps = form.getAuditSteps();
        Operator operator = getCurrentOperator(request);
        int level = form.getAuditStepLevel();
        getAuditStepService().amendAuditStep(operator.getId(), auditStepName,
                auditGroup, auditSteps, level);
        if (form.getId() == null)
            return mapping.findForward("add");
        else
            return mapping.findForward("amend");
    }

    // 以下是孙昊写的
    public ActionForward toAddAuditRuleFirst(ActionMapping mapping,
            ActionForm actionForm, HttpServletRequest request,
            HttpServletResponse response) throws IPBException, Exception {
        AuditRuleForm form = (AuditRuleForm) actionForm;
        request.setAttribute("transactionTypeList", getAuditRuleService()
                .getAuditOperandTypes(false));
        request.setAttribute("validList", getValidList());
        AccountSummary as = WeatherUtil.getLoingInfoFromSession(request);
        form.setAuditStepsCount(1);
        request.setAttribute("initAuditSteps", getCompanyAuditService()
                .getInitAuditSteps(as.getAccount().getId()));
        request.setAttribute("initAuditStepsLength", getCompanyAuditService()
                .getInitAuditSteps(as.getAccount().getId()).size()
                + "");
        return mapping.findForward("success");
    }

    public ActionForward deleteAuditRule(ActionMapping mapping,
            ActionForm actionForm, HttpServletRequest request,
            HttpServletResponse response) throws IPBException, Exception {
        long auditRuleId = Long.parseLong(request.getParameter("id"));
        getAuditRuleService().amendAuditRuleValidity(auditRuleId, false,
                getCurrentOperator(request));
        return mapping.findForward("success");
    }

    public ActionForward addAuditSteps(ActionMapping mapping,
            ActionForm actionForm, HttpServletRequest request,
            HttpServletResponse response) throws IPBException, Exception {
        AuditRuleForm form = (AuditRuleForm) actionForm;
        AccountSummary as = WeatherUtil.getLoingInfoFromSession(request);
        AuditOperandType type = getCompanyAuditService()
                .getAuditOperandTypeById(new Long(form.getTransactionTypeId()));
        request.setAttribute("typeName", type.getName());
        request.setAttribute("typeId", type.getId());
        int size = form.getAuditStepsCount() + 1;
        List auditOperList = getMySpaceService().getAuditOper(
                as.getAccountId() + "");
        List auditStepList = getMySpaceService().getAuditStepList(
                auditOperList, size);
        request.setAttribute("auditOperList", auditOperList);
        request.setAttribute("auditStepList", auditStepList);
        request.setAttribute("size", size + "");
        return mapping.findForward("success");
    }

    public ActionForward toAmendAuditRuleFirst(ActionMapping mapping,
            ActionForm actionForm, HttpServletRequest request,
            HttpServletResponse response) throws IPBException, Exception {
        AuditRuleForm form = (AuditRuleForm) actionForm;
        AuditRule rule = getAuditRuleService().getAuditRuleById(
                (form.getId().longValue()));
        form.setTransactionTypeId(rule.getAuditOperandType().getId()
                .longValue());
        form.setId(form.getId());
        request.setAttribute("transactionTypeList", getAuditRuleService()
                .getAuditOperandTypes(false));
        request.setAttribute("validList", getValidList());
        AccountSummary as = WeatherUtil.getLoingInfoFromSession(request);
        form.setAuditStepsCount(rule.getAuditSteps().size() - 1);
        request.setAttribute("initAuditSteps", getCompanyAuditService()
                .getInitAuditSteps(as.getAccount().getId()));
        request.setAttribute("type", rule.getAuditOperandType());
        return mapping.findForward("success");
    }

    public ActionForward amendAuditSteps(ActionMapping mapping,
            ActionForm actionForm, HttpServletRequest request,
            HttpServletResponse response) throws IPBException, Exception {
        AuditRuleForm form = (AuditRuleForm) actionForm;
        AccountSummary as = WeatherUtil.getLoingInfoFromSession(request);
        AuditOperandType type = getCompanyAuditService()
                .getAuditOperandTypeById(new Long(form.getTransactionTypeId()));
        request.setAttribute("typeName", type.getName());
        request.setAttribute("typeId", type.getId());
        AuditRule rule = getAuditRuleService().getAuditRuleById(
                form.getId().longValue());
        setForm(form, rule);
        int size = form.getAuditStepsCount() + 1;
        List auditOperList = getMySpaceService().getAuditOper(
                as.getAccountId() + "");
        List auditStepList = getMySpaceService().getAuditStepList(
                auditOperList, size);
        request.setAttribute("auditOperList", auditOperList);
        request.setAttribute("auditStepList", auditStepList);
        request.setAttribute("size", size + "");
        return mapping.findForward("success");
    }

    public ActionForward saveOrUpdateAuditRule(ActionMapping mapping,
            ActionForm actionForm, HttpServletRequest request,
            HttpServletResponse response) throws IPBException, Exception {
        AuditRuleForm form = (AuditRuleForm) actionForm;
        AuditOperandType type = getCompanyAuditService()
                .getAuditOperandTypeById(new Long(form.getTransactionTypeId()));
        int size = new Integer(request.getParameter("size")).intValue();
        getCompanyAuditService().saveOrUpdateAuditRule(form, size,
                getCurrentOperator(request), type.getName(),
                type.getId().longValue());
        return mapping.findForward("success");
    }

    public ActionForward auditRuleDetail(ActionMapping mapping,
            ActionForm actionForm, HttpServletRequest request,
            HttpServletResponse response) throws IPBException, Exception {
        AuditRuleForm form = (AuditRuleForm) actionForm;
        AuditRule rule = getAuditRuleService().getAuditRuleById(
                (new Long(request.getParameter("id")).longValue()));
        long accountId = WeatherUtil.getAccountIdFromSession(request);
        if (!rule.getAccount().getId().equals(new Long(accountId))) {
        	rule = null;
        }
        // XXX 测试内容
        form.setTransactionTypeId(rule.getAuditOperandType().getId()
                .longValue());
        request.setAttribute("transactionTypeList", getAuditRuleService()
                .getAuditOperandTypes(false));
        AccountSummary as = WeatherUtil.getLoingInfoFromSession(request);
        request.setAttribute("auditSteps", rule.getAuditSteps().toArray());
        request.setAttribute("transactionTypeList", getAuditRuleService()
                .getAuditOperandTypes(false));
        request.setAttribute("validList", getValidList());
        request.setAttribute("initAuditSteps", getCompanyAuditService()
                .getInitAuditSteps(as.getAccount().getId()));
        request.setAttribute("type", rule.getAuditOperandType());
        request.setAttribute("stepsCount", getCompanyAuditService()
                .getStepName(rule.getAuditSteps().size() - 1));
        return mapping.findForward("success");
    }

    private void setForm(AuditRuleForm form, AuditRule rule) {
        int size = rule.getAuditSteps().size();
        AuditStep[] steps = (AuditStep[]) rule.getAuditSteps().toArray(
                new AuditStep[0]);
        for (int i = 0; i < size; i++) {
            AuditStep step = steps[i];
            int l = step.getAuditGroup().getOperators().toArray().length;
            String[] opers = new String[l];

            for (int a = 0; a < l; a++) {
                Operator op = (Operator) step.getAuditGroup().getOperators()
                        .toArray()[a];
                opers[a] = op.getId().toString();
            }
            switch (i) {
            case 0:
                form.setAuditGroupBeanList0(opers);
                break;
            case 1:
                form.setAuditGroupBeanList1(opers);
                break;
            case 2:
                form.setAuditGroupBeanList2(opers);
                break;
            case 3:
                form.setAuditGroupBeanList3(opers);
                break;
            case 4:
                form.setAuditGroupBeanList4(opers);
                break;
            case 5:
                form.setAuditGroupBeanList5(opers);
                break;

            }
        }

    }
}
